﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using COFE.Core;
using COFE.Core.Lister;
using COFE.Core.Profile;
using COFE.Core.Utils;
using COFE.Core.Validater;
using COFE.Data;
using NUnit.Framework;
using System.Data.Common;
using System.Data.SqlClient;
using COFE.Core.Entry;

namespace COFE.Data.Profile
{
    public class DBEntryManager : IDBEntryManager
    {
        #region Constructor

        static DBEntryManager()
        {
            if (COFEDBConfiguration.Config.RandomEntryKeys)
                StringUtils<IFileSystemInfo>.GuidGeneratorFunc = (fullParsePath) =>
                    {
                        string key, path;
                        COFEPath.ParseFullParseName(fullParsePath, out key, out path);

                        return COFEDBShared.DBOperations.ReadDatabase((context) =>
                            {
                                var entry = context.Entries.FirstOrDefault(
                                    (e) => e.PrimaryVolumeId == key &&
                                        e.ParsePath == path);
                                if (entry != null)
                                    return entry.EntryId;
                                else return Guid.NewGuid();
                            });
                    };
        }

        public DBEntryManager()
        {

        }

        #endregion

        #region Methods
        private bool checkPermission(IUserProfile profile, Entry entry)
        {
            if (profile is AdminUserProfile
                //Is ProfileRoot
                 || entry.PrimaryVolumeId == ProfileRootDirectoryLister.ProfileRootListerKey
                 || profile.FindRegisteredVolume(entry.PrimaryVolumeId) != null)
                return true;
            return false;
        }

        public Entry LookupEntry(COFEDB2 context, IUserProfile profile, Guid entryId)
        {
            Entry retVal = null;

            retVal = context.Entries
                .Include("Parent").Include("Children")
                    .FirstOrDefault(e => e.EntryId == entryId);

            if (retVal != null && checkPermission(profile, retVal))
                return retVal;
            return null;
        }

        public Entry LookupEntry(COFEDB2 context, IUserProfile profile, string fullParseName)
        {
            string key, parseName;
            if (COFEPath.ParseFullParseName(fullParseName, out key, out parseName))
            {
                Entry retVal =
                    context.Entries
                    .Include("Parent").Include("Children")
                    .FirstOrDefault(
                        (e) => e.ParsePath == parseName &&
                                e.PrimaryVolumeId == key);

                if (retVal != null && checkPermission(profile, retVal))
                    return retVal;
            }
            return null;
        }


        public void RemoveEntry(Guid entryId)
        {
            COFEDBShared.DBOperations.UpdateDatabase(
                (context) => LookupEntry(context, COFEShared.AdminUserProfile, entryId),
                (context, dbEntry) =>
                {
                    if (dbEntry == null)
                        return;
                    removeEntry(context, dbEntry);
                    context.SaveChanges();

#if DEBUG
                    Assert.IsNull(COFEDBShared.DBEntryManager.LookupEntry(context,
                        COFEShared.CurrentUserProfile,
                        dbEntry.EntryId));
#endif
                });
        }

        public void ExpireEntry(Guid entryGuid, bool isEntryChanged, bool isListingChanged)
        {
            COFEDBShared.DBOperations.UpdateDatabase(
               (context) => LookupEntry(context, COFEShared.AdminUserProfile, entryGuid),
               (context, dbEntry) =>
               {
                   if (dbEntry == null)
                       return;

                   if (isEntryChanged)
                   {
                       dbEntry.RefreshTime = COFEDBShared.DTMin;
                       dbEntry.PropertyRefreshTime = COFEDBShared.DTMin;
                   }
                   if (isListingChanged)
                   {
                       COFEDBShared.DBEntryPropertyManager.SetProperty(
                           context, dbEntry, DatabaseProperties.LastListTime, COFEDBShared.DTMin);
                   };
                   
                   context.SaveChanges();
               });
        }


        /// <summary>
        /// Remove an entry from database, do recrusive if needed.
        /// Does not call context.savechanges.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="dbEntry"></param>
        private static void removeEntry(COFEDB2 context, Entry dbEntry)
        {
            if (new COFEDBConfiguration().RecrusiveEntryDeletion)
            {
                dbEntry.Children.Load();
                var children = dbEntry.Children.ToArray();
                foreach (var child in children)
                    removeEntry(context, child);
            }
            context.DeleteObject(dbEntry);
        }

        /// <summary>
        /// Create an Database entry based on entryPP.
        /// </summary>
        /// <param name="entryPP"></param>
        /// <param name="parseName"></param>
        /// <param name="addToDB">Add to database immediately, parent is always added to database automatically.</param>
        /// <returns></returns>
        public Entry createEntry(IPropertyProvider entryPP, COFEDB2 context, string parseName = null,
            bool addToDB = false, bool skipParentCheck = false)
        {
            Assert.IsNotInstanceOf<DBPropertyProviderBase>(entryPP);
            Assert.IsNotInstanceOf<DBCachePropertyProvider>(entryPP);

            #region getProperty and getSecProperty method
            Func<object, object> getProperty = (p) =>
            {
                if (entryPP.IsPropertySupported(p))
                    return entryPP.GetProperty(p).Value;
                if (PropertyTypeExtension.HasDefaultValue(p))
                    return PropertyTypeExtension.GetDefaultValue(p);
                throw new NotSupportedException(p.ToString());
            };


            Func<object, object> getSecProperty = (p) =>
            {
                IFileSystemInfo entry = COFEShared.EntryConstructor.CreateEntry(entryPP, EntryConstructionFlags.DefaultWithoutCache);
                if (COFEShared.SecondaryPropertyProviderManager.GetSupportedProperty(entry).Contains(p))
                    return COFEShared.SecondaryPropertyProviderManager.GetProperty(entry, p).Value;
                return null;
            };
            #endregion

            #region Prepare properties          

            string fullParseName = parseName != null ? parseName : getProperty(FileSystemInfoProperties.FullParseName) as String;
            string parentParseName = entryPP.GetProperty(FileSystemInfoProperties.ParentParseName).ValueAsString;


            string primaryVolumeId, parsePath;
            COFEPath.ParseFullParseName(fullParseName, out primaryVolumeId, out parsePath);

            string secondaryVolumeId = primaryVolumeId;
            if (entryPP.IsPropertySupported(FileSystemInfoProperties.SecondaryVolumeKey))
                secondaryVolumeId = getProperty(FileSystemInfoProperties.SecondaryVolumeKey) as String;



#if DEBUG
            Assert.IsFalse(fullParseName.EndsWith("\\"));
            Assert.IsTrue(parentParseName == null || !parentParseName.EndsWith("\\"));
#endif

            //if COFEDBConfiguration.Config.RandomEntryKeys = true,
            //GetDeterministicGuid returns entry Guid in database 
            //or a random guid if not in database.
            Guid entryGuid = StringUtils<IFileSystemInfo>.GetDeterministicGuid(fullParseName);

            string label = getProperty(FileSystemInfoProperties.Label) as String;
            string name = COFEPath.GetFileName(fullParseName);
            string supportedAttributes = entryPP.GetSupportedPropertyString();
            string writableAttributes = entryPP.GetWritablePropertyString();

            var fileAttributes = (FileAttributes)getProperty(FileSystemInfoProperties.FileAttributes);
            var cofeAttributes = (COFEAttributes)getProperty(FileSystemInfoProperties.COFEAttributes);
            bool isDirectory = (fileAttributes & FileAttributes.Directory) != 0;
            int directoryType = isDirectory ? (int)getProperty(DirectoryInfoProperties.DirectoryType) : -1;

            #endregion

            #region Get VolumeIds, and update entryPP if it's FileBasedFSFile

            bool isFileBasedFS = false;
            if (entryPP.IsPropertySupported(DirectoryInfoProperties.FileBasedFSFile))
            {
                isFileBasedFS = true;
                isDirectory = false;
                entryPP = (entryPP.GetProperty(DirectoryInfoProperties.FileBasedFSFile).Value as IInternalFileSystemInfoExA).PrimaryPropertyProvider;
            }

            
            
            //if (secondaryVolumeId != primaryVolumeId && entryPP.IsPropertySupported(DirectoryInfoProperties.FileBasedFSFile))
            //{
            //    entryPP = (getProperty(DirectoryInfoProperties.FileBasedFSFile) as IInternalFileSystemInfoExA).PrimaryPropertyProvider;
            //}
            #endregion

            fileAttributes = (FileAttributes)getProperty(FileSystemInfoProperties.FileAttributes);
            cofeAttributes = (COFEAttributes)getProperty(FileSystemInfoProperties.COFEAttributes);

            #region Check parent Exists

            Guid parentGuid = Guid.Empty;


            //Create cache for parent in database if it's not exists.
            if (!skipParentCheck && !String.IsNullOrEmpty(parentParseName))
            {
                bool parentExists = COFEDBShared.DBEntryManager.Exists(
                    parentParseName, out parentGuid);
                if (!parentExists)
                {
                    var parent = COFEShared.AdminUserProfile.TryParsePath(parentParseName,
                         EntryConstructionFlags.DefaultWithoutCache | EntryConstructionFlags.LookupIfParseFailed)
                        as IInternalDirectoryInfoExA;
                    if (parent == null)
                        throw new Exception(String.Format("Parent is not found. ({0})", parentParseName));
                    var parentEntry = createEntry(parent.PrimaryPropertyProvider, context, parentParseName, true);
                    parentGuid = parentEntry.EntryId;
                }
                Assert.AreNotEqual(Guid.Empty, parentGuid);
            }
            #endregion

            #region Create Database Entry
            Entry newEntry;

            //var sVol = COFEDBShared.Context.Volumes.FirstOrDefault((v) => v.VolumeId == secondaryVolumeId);
            //Assert.IsNotNull(sVol);

            if (cofeAttributes.HasFlag(COFEAttributes.NotCachable))
            {
                //If non-cachable, write Entry only (instead of File/FolderEntry), for lookup path.
                newEntry = Entry.CreateEntry(entryGuid, parentGuid, primaryVolumeId, parsePath, label, name,
                    DateTime.UtcNow, COFEDBShared.DTMin, supportedAttributes, writableAttributes, (int)fileAttributes, (int)cofeAttributes,
                    COFEDBShared.DTMin, COFEDBShared.DTMin, COFEDBShared.DTMin, false);
                newEntry.SecondaryVolumeId = secondaryVolumeId;
            }
            else
            {
                if (isDirectory)
                    newEntry = new FolderEntry()
                    {
                        LastListTime = COFEDBShared.DTMin,
                        DirectoryType = directoryType
                    };
                else
                {
                    newEntry = new FileEntry()
                    {
                        Length = (long)getProperty(FileInfoProperties.Length),
                        CRC = "",
                        IsFileBasedFS = isFileBasedFS
                    };


                }

                DateTime creationTime = (DateTime)getProperty(FileSystemInfoProperties.CreationTimeUtc);
                DateTime lastWriteTime = (DateTime)getProperty(FileSystemInfoProperties.LastWriteTimeUtc);
                DateTime lastAccessTime = (DateTime)getProperty(FileSystemInfoProperties.LastAccessTimeUtc);
                if (creationTime < COFEDBShared.DTMin) creationTime = COFEDBShared.DTMin;
                if (lastWriteTime < COFEDBShared.DTMin) lastWriteTime = COFEDBShared.DTMin;
                if (lastAccessTime < COFEDBShared.DTMin) lastAccessTime = COFEDBShared.DTMin;
                bool isFileSystem = (bool)getProperty(FileSystemInfoProperties.IsFileSystem);

                newEntry.EntryId = entryGuid;
                newEntry.ParentId = parentGuid;
                newEntry.PrimaryVolumeId = primaryVolumeId;
                newEntry.SecondaryVolumeId = secondaryVolumeId;
                newEntry.ParsePath = parsePath;
                newEntry.Label = label;
                newEntry.Name = name;
                newEntry.RefreshTime = DateTime.UtcNow;
                newEntry.PropertyRefreshTime = COFEDBShared.DTMin;
                newEntry.SupportedAttributes = supportedAttributes;
                newEntry.WritableAttributes = writableAttributes;
                newEntry.FileAttributes = (int)fileAttributes;
                newEntry.COFEAttributes = (int)cofeAttributes;
                newEntry.CreationTimeUtc = creationTime;
                newEntry.LastWriteTimeUtc = lastWriteTime;
                newEntry.LastAccessTimeUtc = lastAccessTime;
                newEntry.IsFileSystem = isFileSystem;
            }

            #endregion

            #region Write the entry to Database
            if (addToDB)
            {
                if (!(context.Entries.Any(e => e.EntryId == newEntry.EntryId)))
                {
                    context.Entries.AddObject(newEntry);
                    context.SaveChanges();
                }                
            }


            #endregion

            return newEntry;
        }


        private bool updateEntry(IPropertyProvider entryPP, COFEDB2 context, ref Entry entryToUpdate, string parseName = null)
        {
            string fullParseName = parseName != null ? parseName : entryPP.GetProperty(FileSystemInfoProperties.FullParseName).ValueAsString;
            Assert.IsFalse(fullParseName.EndsWith("\\"));

            Entry entryData = createEntry(entryPP, context, fullParseName, false); //Create an dbEntry but not add to context.
            Guid entryId = entryToUpdate.EntryId;
            entryToUpdate = context.Entries.FirstOrDefault(e => e.EntryId == entryId);
            bool needUpdate = true;

            #region Check whether really need to update.

            if (entryToUpdate.LastWriteTimeUtc == entryData.LastWriteTimeUtc &&
                entryToUpdate.RefreshTime > entryToUpdate.LastWriteTimeUtc)
            {
                if (entryData.Equals(entryToUpdate))
                {
                    needUpdate = false;
                    entryToUpdate.RefreshTime = DateTime.UtcNow;
                    entryToUpdate.PropertyRefreshTime = DateTime.UtcNow;
                }
            }

            #endregion

            if (entryToUpdate.GetType() != entryData.GetType())  //Not same dbEntry type (Folder/File), Delete and add.
            {
                removeEntry(context, entryToUpdate);
                context.Entries.AddObject(entryData);
                entryData.RefreshTime = DateTime.UtcNow;
                //This is required to prevent Sqlite constrain check trigger.
                context.SaveChanges();
            }
            else
            {
                entryToUpdate.RefreshTime = DateTime.UtcNow;
                if (entryToUpdate.LastWriteTimeUtc != entryData.LastWriteTimeUtc &&
                    entryToUpdate.LastWriteTimeUtc != COFEDBShared.DTMin)
                {
                    entryToUpdate.COFEAttributes = entryData.COFEAttributes;
                    entryToUpdate.FileAttributes = entryData.FileAttributes;
                    entryToUpdate.LastWriteTimeUtc = entryData.LastWriteTimeUtc;
                    entryToUpdate.LastAccessTimeUtc = entryData.LastAccessTimeUtc;

                    if (entryToUpdate is FolderEntry)
                    {
                        FolderEntry folderEntryToUpdate = entryToUpdate as FolderEntry;
                        FolderEntry folderEntryData = entryData as FolderEntry;
                        //Update code.
                    }
                    else
                        if (entryToUpdate is FileEntry)
                        {
                            FileEntry fileEntryToUpdate = entryToUpdate as FileEntry;
                            FileEntry fileEntryData = entryData as FileEntry;
                            fileEntryToUpdate.Length = fileEntryData.Length;
                            fileEntryToUpdate.CRC = fileEntryData.CRC;
                        }
                    entryToUpdate.RefreshTime = DateTime.UtcNow;

                }

            }


            return needUpdate;
        }

        private bool updateOrCreateEntry(COFEDB2 context, IPropertyProvider entryPP, out Entry outDbEntry)
        {
            string parseName = entryPP.GetProperty(FileSystemInfoProperties.FullParseName).ValueAsString;

            outDbEntry = COFEDBShared.DBEntryManager.LookupEntry(context, parseName);
            if (outDbEntry != null)
            {
                return updateEntry(entryPP, context, ref outDbEntry);
            }
            else
            {
                outDbEntry = createEntry(entryPP, context, parseName, false);
                context.Entries.AddObject(outDbEntry);
                return true;
            }
        }

        public void UpdateEntry(COFEDB2 context, IEnumerable<IPropertyProvider> entryPPs, bool hasSameParent, bool isFullListing)
        {
#if BENCHMARK
            TestUtils.Benchmark(0, "UpdateEntry", () => {
#endif
            if (entryPPs.FirstOrDefault() == null)
                return;

            int fileCount = 0, subFolderCount = 0;

            #region checkParentInDB
            Func<object, Guid> checkParentInDB = null;
            checkParentInDB = (p) =>
                {
                    IInternalDirectoryInfoExA parent = null;
                    #region Create parent without cache
                    if (p is string)
                    {
                        string parsePath = p as string;
                        if (!this.Exists(parsePath))
                            return Guid.Empty;
                        parent =
                           COFEShared.AdminUserProfile.TryParsePath(
                           parsePath, EntryConstructionFlags.DefaultWithoutCache |
                           EntryConstructionFlags.LookupIfParseFailed) as IInternalDirectoryInfoExA;

                        if (parent == null) throw new System.IO.FileNotFoundException(parsePath);
                    }
                    else
                        if (p is IInternalDirectoryInfoExA)
                        {
                            parent = p as IInternalDirectoryInfoExA;
                            if (!this.Exists(parent.ParseName))
                                return Guid.Empty;

                            if (parent.PrimaryPropertyProvider is IPropertyProviderCache)
                                parent =
                                    COFEShared.AdminUserProfile.TryParsePath(
                                    parent.ParseName,
                                     EntryConstructionFlags.DefaultWithoutCache |
                                     EntryConstructionFlags.LookupIfParseFailed
                                    ) as IInternalDirectoryInfoExA;

                            if (parent == null) throw new System.IO.FileNotFoundException((p as IInternalDirectoryInfoExA).ParseName);
                        }
                    #endregion
                    if (parent != null)
                    {
                        checkParentInDB(parent.Parent); //Make sure parent's parent is exist in db.
                        createEntry(parent.PrimaryPropertyProvider, context, null, true);
                    }

                    return parent != null ? parent.GetId() : Guid.Empty;
                };
            #endregion

            Dictionary<IPropertyProvider, Entry> updateDic = new Dictionary<IPropertyProvider, Entry>();

            #region check each entries's parent to make sure they re exists (checkParentInDB() has both locks.)

            Func<IPropertyProvider, Guid> getParentId = (entryPP) =>
                {
                    if (entryPP.IsPropertySupported(FileSystemInfoProperties.Parent))
                        return checkParentInDB(entryPP.GetProperty(FileSystemInfoProperties.Parent).Value);
                    else return checkParentInDB(entryPP.GetProperty(FileSystemInfoProperties.ParentParseName).ValueAsString);


                    //bool isFolder = (((FileAttributes)entryPP.GetProperty(FileSystemInfoProperties.FileAttributes).Value)
                    //    & FileAttributes.Directory) != 0;

                };

            if (hasSameParent)
            {
                var entryIds = new List<Guid>();

                foreach (var entryPP in entryPPs)
                {
                    bool isFolder = (((FileAttributes)entryPP.GetProperty(FileSystemInfoProperties.FileAttributes).Value)
                        & FileAttributes.Directory) != 0;
                    if (isFolder)
                        subFolderCount++;
                    else fileCount++;
                    entryIds.Add(StringUtils<IFileSystemInfo>.GetDeterministicGuid(entryPP.GetParseName()));
                }

                var parentId = getParentId(entryPPs.First());
                if (parentId != Guid.Empty)
                {
                    foreach (var c in context.Entries.Where(e => e.ParentId == parentId))
                        if (!(entryIds.Contains(c.EntryId)))
                            removeEntry(context, c);
                    context.SaveChanges();
                }
            }
            else
                Parallel.ForEach(entryPPs, (entryPP) =>
                    {
                        getParentId(entryPP);
                    });

            #endregion


            #region update or create each entry. (updateOrCreateEntry() have both locks.)

            //Faster
            Parallel.ForEach(entryPPs,
                (entryPP) =>
                {
                    using (var context2 =
                        new COFEDB2(context.Connection.ConnectionString))
                    {
                        Entry dummy = null;
#if BENCHMARK
                        TestUtils.Benchmark(1, "updateOrCreateEntry", () => {
#endif
                        updateOrCreateEntry(context2, entryPP, out dummy);
#if BENCHMARK
                        });
#endif
                        context2.SaveChanges();
                        COFEDBShared.DBEntryPropertyManager
                            .CachePrimaryProperties(context2, dummy, entryPP);
                        context2.SaveChanges();
                    }
                });

            foreach (var entryPP in entryPPs)
            {
                var entryId = entryPP.GetId();
                CachePropertiesWork.ScheduleWork(entryId, entryPP.GetParseName());
            }

            #endregion

            #region update last el time if it's full listing.
            if (hasSameParent && isFullListing)
            {
                //Is full listing, so update parent's LastList time.
                string parentParseName = entryPPs.FirstOrDefault().GetProperty(FileSystemInfoProperties.ParentParseName).ValueAsString;
                //entryPPs[0].GetProperty(FileSystemInfoProperties.ParentParseName).ValueAsString;
                //Assert.IsNotNullOrEmpty(parentParseName);
                if (parentParseName != null)
                {
                    var parentDbEntry = this.LookupEntry(context, parentParseName);

                    if (parentDbEntry == null)
                        throw new Exception("Parent entry not found in database. " + parentParseName);
                    COFEDBShared.DBEntryPropertyManager.SetProperty(context, parentDbEntry, DatabaseProperties.LastListTime, DateTime.UtcNow);
                    COFEDBShared.DBEntryPropertyManager.SetProperty(context, parentDbEntry, DirectoryInfoProperties.SubFolderCount, subFolderCount);
                    COFEDBShared.DBEntryPropertyManager.SetProperty(context, parentDbEntry, DirectoryInfoProperties.FileCount, fileCount);
                    context.SaveChanges();
                }
            }
            #endregion
#if BENCHMARK
                });
#endif
        }

        private bool expiredProps(DateTime refreshTIme)
        {
            return refreshTIme < DateTime.UtcNow.Subtract(COFEDBShared.TTLPropertyValues);
        }

        private void updateProperties(COFEDB2 context, Entry retEntry, IPropertyProvider entryPP)
        {
            if (expiredProps(retEntry.PropertyRefreshTime))
            {
                CachePropertiesWork.ScheduleWork(entryPP);
                //COFEDBShared.DBEntryPropertyManager.CacheProperties(retEntry.EntryId, entryPP);
            }
        }

        public Entry UpdateEntry(COFEDB2 context, IPropertyProvider entryPP)
        {
            Entry retEntry;

            if (entryPP is IPropertyProviderCache)
                entryPP = (entryPP as IPropertyProviderCache).CachingPropertyProvider;

            if (updateOrCreateEntry(context, entryPP, out retEntry)) //If modified and updated.
                updateProperties(context, retEntry, entryPP);  //Update properties too.
            context.SaveChanges();
            //Cache PrimaryProperties
            COFEDBShared.DBEntryPropertyManager
                            .CachePrimaryProperties(context, retEntry, entryPP);
            context.SaveChanges();
            //#if DEBUG
            //            string parseName = entryPP.GetProperty(FileSystemInfoProperties.FullParseName).ValueAsString;
            //            Assert.IsNotNull(retEntry);
            //            retEntry = this.LookupEntry(parseName);
            //            Assert.IsNotNull(retEntry);
            //#endif            

            return retEntry;
        }

        public void UpdateDirectoryIsEmpty(COFEDB2 context, IPropertyProvider dirPP)
        {
            string parseName = dirPP.GetProperty(FileSystemInfoProperties.FullParseName).ValueAsString;
            var dbEntry = this.LookupEntry(context, parseName);// as FolderEntry;
            if (dbEntry != null)
            {
                //COFEDBShared.DBEntryPropertyManager.SetProperty(context,
                //    dbEntry, DatabaseProperties.LastListTime, DateTime.UtcNow);
                //COFEDBShared.DBEntryPropertyManager.SetProperty(context,
                //    dbEntry, DirectoryInfoProperties.SubFolderCount, 0);
                //COFEDBShared.DBEntryPropertyManager.SetProperty(context,
                //    dbEntry, DirectoryInfoProperties.FileCount, 0);
                //dbEntry.FileCount = 0;
                //dbEntry.SubFolderCount = 0;
                //dbEntry.LastListTime = DateTime.UtcNow;
                //context.SaveChanges();
            }
            else
            {
                dbEntry = createEntry(dirPP, context, parseName, true);
            }

            COFEDBShared.DBEntryPropertyManager.SetProperty(context,
                   dbEntry, DatabaseProperties.LastListTime, DateTime.UtcNow);
            COFEDBShared.DBEntryPropertyManager.SetProperty(context,
                dbEntry, DirectoryInfoProperties.SubFolderCount, 0);
            COFEDBShared.DBEntryPropertyManager.SetProperty(context,
                dbEntry, DirectoryInfoProperties.FileCount, 0);
            context.SaveChanges();


        }

        public void UpdateDirectoryIsEmpty(IPropertyProvider dirPP)
        {
            COFEDBShared.DBOperations.UpdateDatabase(
                (context) =>
                {
                    UpdateDirectoryIsEmpty(context, dirPP);
                });


        }

        #endregion

        #region Data

        #endregion

        #region Public Properties



        #endregion







    }
}
